#!/usr/bin/python
# coding=utf-8
   
"""批量调整照片大小

python imaging.py -r 0 -s path -t path
"""
__author__ ='BOBO'
__email__ = 'tonywang1988' 
VERSION = "Photo Resizer v1.0"

import os, sys, re, time, getopt, string
import shutil
import glob
import Image

opts, args = getopt.getopt(sys.argv[1:], "hs:t:r:", ["help", "src=", "to=", "transpose="])
#原路径
src_path = ""
#缩放后路径
to_path = ""
#是否旋转
is_transpose = '0'

def usage():
    print ("Usage:imaging.py [ops]")

if not opts:
    usage()
    sys.exit()
else:
    for op, value in opts:
#        print "op:value="+op+":"+value
        if op == "-s" or op == "--src":
            src_path = value
        elif op == "-t" or op == "--to":
            to_path = value
        elif op == "-r" or op == "--transpose":
            is_transpose = value
        elif op == "-h" or op == "--help":
            usage()            
            sys.exit()



class PicResizer:
  """根据指定的目录，对该目录下的所有照片进行大小调整
  """

  def __init__(self, picpath, bakpath):
      '''初始化参数'''
      self.picpath = picpath
      self.bakpath = bakpath

#      logfile = bakpath + "/log" + time.strftime("%Y%m%d%H%M") + ".txt"
#      self.log = open(logfile, "a")

  def pic_walker(self, path):
      '''获取指定目录下的所有JPG照片，不递归深入查找'''
      target = []
      for files in glob.glob(path + "/*.jpg"):
          filepath,filename = os.path.split(files)  # todo: mark
          target.append(filename)

      return target

  def check_folder(self, subFolderName):
      '''检查目标文件夹是否存在，不存在则创建之'''

#      foldername = self.bakpath + '/' + subFolderName
      foldername = self.bakpath
      print foldername

      if not os.path.isdir(foldername):
          os.mkdir(foldername)

      #return 0
      return foldername

  def pic_info(self, img):
      '''获取照片的尺寸'''
      w, h = img.size
      if  w>h:
          return w, h, 0  # 横版照片
      else:
          return w, h, 1  # 竖版照片

  def comp_num(self, x, y):
      '''比较两个实数
      如果是用直接比较话会出现经典的整数除得0问题
      '''

      x = float(x)
      y = float(y)
      return float(x/y)

  def pic_resize(self, picname, p_w, p_h):
      '''根据设定的尺寸，对指定照片进行像素调整'''

      # 获取指定照片的规格，一般是1024,768
      img = Image.open(picname)
      w, h, isVertical = self.pic_info(img)
      print "isVertical=="+str(isVertical)
      if is_transpose == '1':
         if isVertical == 0:
            #横版
            p_w, p_h = p_h, p_w
            img = img.transpose( Image.ROTATE_270 )

      # 判断照片横竖，为竖版的话对调w,h
      if isVertical:
          p_w, p_h = p_h, p_w

      # 如果照片调整比例合适，直接输出
      if self.comp_num(p_h, p_w) == self.comp_num(h, w):
          target = img.resize(
                              (int(p_w), int(p_h)),
                              Image.ANTIALIAS  # hack: 参数呐！高保真必备！
                             )
          # ANTIALIAS: a high-quality downsampling filter
          # BILINEAR: linear interpolation in a 2x2 environment
          # BICUBIC: cubic spline interpolation in a 4x4 environment

          return target

      # 比例不合适就需要对照片进行计算，保证输出照片的正中位置
      # 算法灵感来源于ColorStrom
      if self.comp_num(p_h, p_w) > self.comp_num(h, w):
          # 240/320 > 360/576 偏高照片的处理

          # 以高为基准先调整照片大小
          p_w_n = p_h * self.comp_num(w,h)  # 根据新高按比例设置新宽
          temp_img = img.resize(
                                (int(p_w_n), int(p_h)),
                                Image.ANTIALIAS
                               )

          # 获取中间选定大小区域
          c = (p_w_n - p_w)/2  # 边条大小
          box = (c, 0, c+p_w, p_h)  # 选定容器
          box = tuple(map(int, box))  # 转换成crop需要的int形参数
          target = temp_img.crop(box)

          return target

      else:
          # 偏宽的照片

          # 以宽为基准先调整照片大小
          p_h_n = p_w * self.comp_num(h, w)  # 根据新宽按比例设置新高
          temp_img = img.resize(
                                (int(p_w), int(p_h_n)),
                                Image.ANTIALIAS
                               )

          # 获取新图像
          c = (p_h_n - p_h)/2
          box = (0, c, p_w, c+p_h)
          box = tuple(map(int, box))
          target = temp_img.crop(box)

          return target  

  def run_auto(self, *args):
      '''运行调整照片尺寸进程
      接纳规格列表，每个规格为一个tuple
      '''

      # 获取所有图片列表
      imglist = self.pic_walker(self.picpath)

      # 处理照片
      for img in imglist:
          imgfile = self.picpath + "/" + img  # 完整照片名称

#          try:
          for std in args:
              w, h = std[0], std[1]  # 获取目标照片规格

              # 定义目标文件
              opfile = self.check_folder(str(w)+"x"+str(h)) + "/" + img

              tempimg = self.pic_resize(imgfile, int(w), int(h))
              tempimg.save(opfile, 'jpeg')

#              self.log.write(str(img) + "\tOK\n")
#          except:
#              self.log.write(str(img) + "\tErr\n")

          print '-->' + img

      print "Done."



def main():
  '''主函数'''

  # picpath = bakpath = raw_input("type your photo's path:")
  # 修改源照片文件夹路径
  picpath = src_path
  # 修改为你的目标路径
  bakpath = to_path
  
  if not os.path.exists(picpath):
    print "src path need exists"
    sys.exit()
  if os.path.exists(bakpath):
    shutil.rmtree(bakpath)
  os.mkdir(bakpath)

#  sys.exit();
  # 实例一个进程并运行
  resizer = PicResizer(picpath, bakpath)
  resizer.run_auto((800, 480))


if __name__ == "__main__":
  sys.exit(main())
